冴えないAWS環境の育てかた α
中山です
ソリューションアーキテクトとして、AWS環境の利活用をお手伝いするお仕事をしています。
まれによく見るAWS環境
とりあえずこれを見てほしい。
これが絶対にだめと言いたいわけではないです。 一時的な検証環境だったり、とにかくスピード重視でサービスをデリバリーさせる必要があったり、サービスの提供者側が何ら責任を負わない・障害時のビジネスインパクトが無い(そんな状況あるのか?)という前提があったり、状況次第ではこれで十分な時もあると思います。 しかし、一般的な業務システムやサービスの場合にはいろんな意味で不十分でしょう。
では、このような環境をどのように育てていくとよいでしょうか。 この記事では、そんな育てかたの一例を紹介していきたいと思います。
なお、本記事はくっそ長いです。
ちなみに、最終的にはこうなります。
文字が小さすぎて読めない! ちょっとそこのハ○キルーペ貸してくれーw
前提条件
最初に挙げた環境ですが、以下のような前提だとします。
- サーバー上で動作しているものは一般的なWebアプリケーション
- リレーショナルデータベースを利用している
- 1つのEC2インスタンス上で全部構成されている
これ以降、どのような改善ができるかの述べていきますが、 アプリケーション自体の改善については基本的にスコープ外とします(サーバーレスやコンテナへの移行などは本記事では扱いません)。 ウェブサーバー・アプリケーションサーバーはスケールアウト可能であると仮定します。
また、AWSアカウントは1つだけ利用するような状況を想定しています(マルチアカウント管理はスコープ外)。
育て方のアプローチ
育てる要素はいろいろありますが、今回は以下の4つに分けて育ててみます。
- AWSアカウントの育てかた
- ネットワークの育てかた
- サーバーの育てかた
- データストアの育てかた
あと、長くなるので一つ一つの育成策に対する細かい解説はしません。 公式ドキュメントなどを参照しましょう。
評価基準
AWSにはWell Architected Frameworkというものがあります。
AWS Well-Architected Framework
以下の5つの柱に基づいて、設計や環境がベストプラクティスに基づいているかを確認することができます。
- Operational Excellence
- Security
- Reliability
- Performance Efficiency
- Cost Optimization
厳密にこれに則っていくわけではありませんが、なんとなく意識しながらこの記事を書いていこうと思います。
AWSアカウントの育てかた
まずは、AWSアカウント自体を育てます。この部分はどんなアプリケーションを稼働させる場合であってもできること・やるべきことです。
利用するサービス
- CloudTrail
- IAM
- Access Analyzer
- Config
- Budgets
- GuardDuty
- Detective
- Security Hub
- Trusted Advisor
- Personal Health Dashboard
- AWS Support
一部の作業項目では、AWS ChatbotおよびAmazon SNSを利用しています。
育てる
まず、何をやるか列挙します。
- CloudTrail / 有効化(全リージョン)
- CloudTrail / 改ざん検知
- CloudTrail / CloudWatch Logsへの配信もしくはAthenaのテーブル定義
- CloudTrail / CloudTrail Insightsの有効化
- IAM / ルートアカウントのMFA有効化
- IAM / パスワードポリシーの強化
- IAM / IAM Userの作成
- IAM / IAM UserにMFAを設定する
- IAM / IAM Groupの作成および権限付与
- IAM / IAM Userによる請求情報へのアクセス許可
- Access Analyzer / 有効化
- Access Analyzer / イベント通知
- Config / 有効化
- Config / すべてのリソースの記録を取得
- Budgets / 予算を設定
- Cost Explorer / 有効化
- コスト配分タグの設定
- GuardDuty / 全リージョンでの有効化
- GuardDuty / イベント通知
- Detective / 有効化
- Security Hub / 有効化
- Security Hub / Security Standardの有効化
- Security Hub / イベントの通知
- Trusted Advisor / イベントの通知
- Personal Health Dashboard (AWS Health) / イベントの通知
- AWS Support / プランの変更
- Artifact / サービスアグリーメントの変更(準拠法、管轄裁判所)
- 代替連絡先の設定
- 支払通貨の変更
CloudTrail / 有効化(全リージョン)
CloudTrailを有効化しましょう。
これにより、AWSのAPIを「いつ」「だれが」「どのように」利用したのかを把握できるようになります。
この際、Multi region Trailが有効になっているか確認しましょう。 なお、現在はコンソールで設定する場合には必ず有効なるようです。
インシデントの調査に使用できますし、内部不正の抑止力にもなります。
CloudTrail / 改ざん検知
Trailを作成する際にファイルの整合性をチェックできるオプションを有効にしましょう。
Validating CloudTrail Log File Integrity
改ざんされる余地があると、正しく監査できない可能性がでてしまいます。
CloudTrail / CloudWatch Logsへの配信もしくはAthenaのテーブル定義
Trailを作成する際にCloudWatch Logsへのログの配信を設定しましょう。
Monitoring CloudTrail Log Files with Amazon CloudWatch Logs
CloudWatch Logsのコストが気になるときには、S3上のログをすぐに分析できるようにAthenaのテーブルを定義しておきましょう。
CloudTrailのログはコンソールでのフィルタリングも可能ですが、より高度な分析をしたい場合には事前にこれらの設定をしておくと良いでしょう。
CloudTrail / CloudTrail Insightsの有効化
Insights Eventsの取得を有効化しましょう。
Logging Insights Events for Trails
幅広いサービスの書き込み系イベントについて、通常とは異なる挙動を検知できます。 大事なアカウントで利用するとよいのではないでしょうか。
IAM / ルートアカウントのMFA有効化
ルートアカウントにMFAを設定しましょう。
Using Multi-Factor Authentication (MFA) in AWS
説明は不要ですよね(にっこり
IAM / パスワードポリシーの強化
パスワードポリシーを強化しましょう。
Setting an Account Password Policy for IAM Users
組織のポリシーがあればそれに準じましょう。
最近はパスワードの定期変更を求めないガイドも増えてきました。
IAM / IAM Userの作成
一人一人にIAM Userを発行しましょう。
Creating an IAM User in Your AWS Account
ユーザーを共有してしまうと、CloudTrailでログを取得する意味もなくなります。 各操作を誰が行ったのか、識別できるように正しいユーザーの運用を行いましょう。
IAM / IAM UserにMFAを設定する
IAM UserにMFAを設定しましょう。
Using Multi-Factor Authentication (MFA) in AWS
最近のセキュリティインシデントを鑑みると、パスワード (What you know) だけで良いはずがありません。
デバイスは好きなものを選べばいいと思いますが、設定をデバイス間で同期できるものは適切に運用しましょう。
なお、MFAの設定はセルフサービスで展開すると管理者の負担は小さくなると思います。 デバイスが壊れたりしたときはさすがに管理者の出番ですが。
IAM: Allows IAM Users to Self-Manage an MFA Device
MFAを設定しない横着なやつに備えて以下のようなポリシーを設定して差し上げましょう。
Amazon EC2: Requires MFA (GetSessionToken) for Specific EC2 Operations
IAM / IAM Groupの作成および権限付与
同じ役割のユーザーはIAM Groupでまとめたうえで権限を付与しましょう。
Attaching a Policy to an IAM Group
ユーザー毎に権限付与すると管理が煩雑になります。 そのため、Groupに対して権限を付与しましょう。 Groupのメンバーには自動的に権限が付与されます。
なお、AWSが定義済みのポリシーを利用すると設計の負担を軽減できます。
この際、IAMの管理権限を安易に付与するのは控えましょう。 どうしてもIAMの権限を渡したいなら、Permissions boundaryを利用して意図しない特権昇格を予防しましょう。
Permissions Boundaries for IAM Entities
IAM / IAM Userによる請求情報へのアクセス許可
IAM Userに対して請求情報へのアクセスを許可しましょう。
Overview of managing access permissions
デフォルトだとrootアカウントしか請求情報へのアクセス権を持っていません。 しかし、rootアカウントを日常的に利用するのは望ましくありません。 IAM Userが参照できるようにしておきましょう。
Access Analyzer / 有効化
Access Analyzerを有効化して意図しないアクセス許可を管理しましょう。
S3などのリソースにアクセスポリシーを設定できますが、安易に設定して機密情報が世界中にフルオープンになることがあります。 有効化して、ポリシーを適切に管理しましょう。
Access Analyzer / イベント通知
Access Analyzerのイベントを通知しましょう。
Monitoring AWS IAM Access Analyzer with Amazon EventBridge
検知されたイベントを確認し、必要なアクセス許可はアーカイブしましょう。 意図しないイベントの場合には適切な状態へ是正しましょう。
Config / 有効化
Configを有効化しましょう。
Setting Up AWS Config with the Console
リソース変更の過程が分かるので、トラブルシュートなどでも役に立ちます。
Config / すべてのリソースの記録を取得
Configを有効化する際、IAMを含むサポート対象のすべてのリソースで構成情報を取得しましょう。
Budgets / 予算を設定
料金が予算を超えないようにBudgetsを設定しましょう。
実際に使った金額が閾値に達したら通知することもできますし、予算に達しそうになったら通知することもできます。 なお、ChatbotでSlackなどに通知することもできます。
Using AWS Chatbot with other AWS services
Cost Explorer / 有効化
Cost Explorerを有効化しましょう。
「何でコストが発生しているのか」を分析できないと「コストを削減したい・・・」と思ったときに困ります。
コスト配分タグの設定
コスト配分タブを設定しましょう。
独自の観点で分析したいときにお好みでどうぞ。 一つのアカウントを多目的に利用している、かつ経費の配布部門が分かれているケースなどで必要になるでしょう。 ただし、ネットワーク転送量など厳密に分離できない課金要素もあるので、厳密な分離が必要な場合はAWSアカウントを分けましょう。
GuardDuty / 全リージョンでの有効化
GuardDutyを全リージョンで有効化しましょう。
CloudTrail / VPC FlowLogs / DNSなどのログに基づいてセキュリティリスクのあるイベントを検知してくれます。 あくまでも検知です。
いくらログを取得していても、「どのアクティビティがヤバいか」を判断するのは難しいので、非常に助かります。
GuardDuty / イベント通知
GuardDutyのイベントを通知しましょう。
Creating custom responses to GuardDuty findings with Amazon CloudWatch Events
問題に気がつけなければ意味ないので、必ず通知しましょう。 Slackに通知したいときはChatbotでどうぞ。
Using AWS Chatbot with other AWS services
Detective / 有効化
Detectiveを有効化しましょう。
いざという時にセキュリティログ・イベントを調査できるように有効化しましょう。
Security Hub / 有効化
Security Hubを有効化しましょう。
セキュリティイベントの集約も良い機能ですが、個人的には次のSecurity Standardを使いたいので有効化しておいていただきたいです。
Security Hub / Security Standardの有効化
Security Standardを利用しましょう。
Disabling or enabling a security standard
Security Standardを利用することで、AWSリソースの設定にセキュリティリスクがないか評価してくれます。 設定は非常に簡単で、裏ではConfig Rulesが利用されています。
ルールセットは3種類あります。 内容を確認し、要件にマッチしたものを選ぶと良いでしょう。 一旦は全部有効化して、その結果を踏まえて判断するのでも良いと思います。
CIS AWS Foundations Benchmark standard
Payment Card Industry Data Security Standard (PCI DSS)
AWS Foundational Security Best Practices standard
Security Hub / イベントの通知
Security Standardで検知した違反を通知しましょう。
Configuring a CloudWatch Events rule for automatically sent findings
他のサービス同様、問題の発生に気づけないと意味がないので、適切に通知設定を実施しましょう。
ただし、GuardDutyやAccess AnalyzerなどのいくつかのサービスはデフォルトでSecurity Hubと連携しているので、何も考えずに設定だけすると連携するサービスに関連する通知が重複します。 Security Hubと各サービスとの連携を無効化することも可能なので、必要に応じて調整してください。
Disabling and enabling the flow of findings from an integration (console)
あと、Chatbotとの連携もできます。
Using AWS Chatbot with other AWS services
Trusted Advisor / イベントの通知
Trusted Advisorで検知した問題を通知しましょう。
Monitoring Trusted Advisor check results with Amazon CloudWatch Events
Trusted Advisorでは、セキュリティ以外の観点で環境を評価してくれるのでこちらも確認することをお勧めします。
Personal Health Dashboard (AWS Health) / イベントの通知
Healthイベントを通知しましょう。
Monitor for AWS Health events with Amazon CloudWatch Events
メンテナンス通知を見逃してインスタンス再起動したら、きっと後悔しますよ。
これもChatbotいけます。
Using AWS Chatbot with other AWS services
AWS Support / プランの変更
適切なサポートプランを設定しましょう。
Changing your AWS support plan
各プランのサービスレベルに応じて適切なものを選択してください。
Artifact / サービスアグリーメントの変更(準拠法、管轄裁判所)
(必要なら)サービスアグリーメントを変更しましょう。
Managing an Agreement for a Single Account
「日本の法律を準拠法として採用し、本契約に関するあらゆる紛争に関する第一審裁判所を東京地方裁判所とする」ことができます。 そもそも、AWSと事を構える可能性がどれだけあるのか分かりませんが。
代替連絡先の設定
代替連絡先を設定しましょう。
Adding, changing, or removing alternate contacts
お金やセキュリティ的な通知をちゃんと認識できるようにしましょう。 当然、受け取った通知はちゃんと確認しましょう。
支払通貨の変更
支払い通貨を日本円に変更しましょう。
Changing which currency you use to pay your bill
デフォルトだと海外利用扱いなので、カードの海外利用の手数料分お安くなります。
小まとめ
ということで、AWSアカウント自体はこんな感じで育ちました。
ここまでは、AWSを何のために使う場合でもやるべき内容ですね。THE 基礎。
ネットワークの育てかた
次に、ネットワークを育てていきます。
利用するサービス
材料は以下の通りです。
- Route53
- CloudFront
- ACM
- WAF
- Subnet(VPC)
- Route Table(VPC)
- ELB
- VPC FlowLogs(VPC)
- Security Group(VPC)
育てる
やることは以下の通り。
- Route53 / ドメインを登録(もしくは移管)
- Route53 / ヘルスチェックの有効化
- CloudFront / ディストリビューションの作成
- CloudFront / 追加のメトリックを有効化
- CloudFront / アクセスログの取得
- CloudFront / 特定地域からのアクセスをブロック
- CloudFront / カスタムエラーレスポンスとしてSorry Pageを構成
- CloudFront / 監視
- ACM / サーバー証明書の作成
- ACM / CloudFrontへの関連付けと適切なセキュリティポリシーの選択
- AWS WAF / WebACLの作成
- AWS WAF / ログの収集
- VPC / 複数のAvailability ZoneにSubnetを作成
- VPC / 通信の範囲に応じてSubnetを作成
- VPC / NAT Gatewayの作成
- VPC / Subnetの種類別にRoute Tableを定義
- ELB / Application Load Balancer (ALB) の作成
- ELB + CloudFront / CloudFrontからのアクセスのみを許可
- ELB / HTTP Desync緩和モードの設定
- ELB / 監視
- VPC / VPC FlowLogの作成
Route53 / ドメインを登録(もしくは移管)
Route53でドメインをホストしましょう。
Route53でドメインを新たに登録することもできますし、ドメインを移管することもできます。
Registering domain names using Amazon Route 53
既存のレジストラーを継続して利用するのもいいですが、管理コンソールにログインする際にMFAが利用できなかったり監査ログが取得できないといった場合には移管を検討するとよいのではないでしょうか。
あと、SLAも100%ですし。
Amazon Route 53 サービスレベルアグリーメント
Route53 / ヘルスチェックの有効化
ヘルスチェックを利用してみましょう。
Creating, updating, and deleting health checks
サービスの利用者視点で正常性やパフォーマンスを見ることも大事です。 実際はRoute53 Health Checkerから監視されます。
もちろん、通知もご一緒に。
Monitoring health check status and getting notifications
より高度な監視は、Syntheticsで。
CloudFront / ディストリビューションの作成
CloudFrontを利用しましょう。
Values That You Specify When You Create or Update a Distribution
パフォーマンスの向上だけでなく、DDoS攻撃への耐性を向上させることができます。
とりあえず、静的コンテンツのキャッシュからはじめるとよいのではないでしょうか。 動的なコンテンツでも利用できます。
ちなみに、最近キャッシュキーやオリジンリクエストに関するポリシーを独立したリソースとして扱えるようになりました。
CloudFront / 追加のメトリックを有効化
追加のメトリクスを有効化しよう。
Viewing additional CloudFront distribution metrics
ほしいメトリクスがある場合には有効化を検討しましょう。
CloudFront / アクセスログの取得
アクセスログを取得しましょう。
Configuring and Using Standard Logs (Access Logs)
事故調査など、様々な機会でログを利用することがあると思います。 取得しておきましょう。
ちなみに、最近リアルタイムでログを取得できるようになりました。 こっちはお好みで。
CloudFront / 特定地域からのアクセスをブロック
(必要なら)特定地域からのアクセスをブロックしましょう。
Restricting the Geographic Distribution of Your Content
精度はそこそこですし、状況に応じて検討したらよいと思います。
CloudFront / カスタムエラーレスポンスとしてSorry Pageを構成
Sorry Pageを用意しましょう。
Generating Custom Error Responses
オリジンで障害が発生したときに生のエラーが出てしまうとあまりイメージがよろしくないので、状況を制御できてる感を出していきましょう。
CloudFront / 監視
CloudFrontを監視しましょう。
Viewing CloudFront and Lambda@Edge metrics
エラーレートやレイテンシなどを監視しておくとよいのではないでしょうか。
CloudWatch Alarmを利用する場合の通知にはChatbotを利用できます。
ACM / サーバー証明書の作成
ACMでサーバー証明書を発行しましょう。
Requesting a Public Certificate
ドメイン認証ですが、無料です。
EV証明書を利用したい場合にはインポートもできるけど、EV証明書じゃないと絶対ダメなケースってどれくらいあるんですかね?
Importing Certificates into AWS Certificate Manager
ACM / CloudFrontへの関連付けと適切なセキュリティポリシーの選択
証明書を発行したらCloudFrontと紐付けましょう。
その際、適切なセキュリティポリシーを指定しましょう。 よほど古いクライアントをサポートする必要が無い限り、TLS1.2以降のみをサポートするようにしましょう。 なお、最近TLS1.3もサポートされました。 やったね!
Supported protocols and ciphers between viewers and CloudFront
AWS WAF / WebACLの作成
AWS WAFでWebアプリケーションを保護しましょう。
あくまでも、緩和策として利用しましょう。
なお、ルールはアプリケーションの種類にマッチしたマネージドルールを利用するのがお手軽でおすすめです。
運用開始時はカウントから(いきなりブロックしない)始めるといいんじゃないでしょうか。
AWS WAF / ログの収集
AWS WAFでもログを収集しましょう。
Logging Web ACL traffic information
Firehose経由で収集できます。
VPC / 複数のAvailability ZoneにSubnetを作成
複数のAvailability ZoneにまたがってSubnetを作成しましょう。
Availability Zoneについてはこちらをご確認ください。
サーバーをAZに跨がって展開できればAZがぶっ壊れても、ある程度は大丈夫です。
ここから、1つのインスタンスを以下のように分割することを前提に話を進めます。
- リレーショナルデータベースを別のインスタンスで稼働させる
- Web・アプリケーションサーバーを冗長化する
VPC / 通信の範囲に応じてSubnetを作成
サーバーの通信範囲に応じたSubnetを作成しましょう。
インターネットから直接アクセスされるリソースもあれば、インターネット「へ」のアクセスだけできればよいリソースあります。 ものによっては、VPC内で通信できればよいものもあります。
どこに通信できるかはRoute Tableで制御できますが、 前の手順でAZに跨がって作成したSubnetをさらにルーティングの要件毎に作成します。 Route Tableの設定は後述します。
今回は、以下の3種類のSubnetを作成することとします。
- Public
- インターネットからのリクエストを受け付けるリソースを配置する
- Private
- インターネットからのリクエストは受け付けないが、インターネットへアクセスする必要があるリソースを配置する
- Data
- インターネットと通信する必要がないリソースを配置する(後述するAWS Managedなリソースを配置する予定)
具体的な構成はこの辺が参考になるのでどうぞ。
Modular and Scalable VPC Architecture
VPC / NAT Gatewayの作成
NAT Gatewayを利用しましょう。
プライベートなサブネットからインターネットへアクセスするときに必要となる要素です。
EC2インスタンスでもNATできますが、管理がめんどくさいのでマネージドなこちらを利用しましょう。 コストを限界まで抑えたい場合はNATインスタンスをどうぞ。
VPC / Subnetの種類別にRoute Tableを定義
Subnetの種類毎にルートテーブルを定義しましょう。
設定イメージは以下の通りです。
- Public
- Internet Gatewayをデフォルトルートに設定
- Private
- NAT Gatewayをデフォルトルートに設定
- NAT GatewayはAZに依存するのでRoute TableをAZ毎に定義
- Data
- デフォルトのルート(VPC内でのルーティング)のみ
ELB / Application Load Balancer (ALB) の作成
ELBを利用してウェブサーバー・アプリケーションサーバーをリクエストの振り分けを行いましょう。 一般的なWebサービスならALBをどうぞ。
Getting started with Application Load Balancers
EC2インスタンスはホストの障害などで止まることがあります。 止まらないことを祈る、というのはエンジニアのすることではありません。 Design for Failureでお願いします。
本当はAutoScalingまで言及してもよいのですが、アプリケーションが対応できるかはケースバイケース(いにしえのアプリケーションでは何かしら問題があることが多い)なので、本記事では言及しません。 そういったアプリケーションは12-Factor App原則に反していることが多い印象です。
データベースについては後ほど言及します。
ELB + CloudFront / CloudFrontからのアクセスのみを許可
CloudFrontからオリジンへのリクエストを転送する際、カスタムヘッダーをつけることでELBへのアクセスをCloudFrontに限定できます。
Adding Custom Headers to Origin Requests
20190730 AWS Black Belt Online Seminar Amazon CloudFrontの概要
ALBでは、リクエストヘッダーの内容に応じて応答を変えることができます。
指定したターゲットに転送するほかに、リダイレクトや固定レスポンスをALBから返すことも可能です。
IPアドレスでも実現可能ですが、運用がめんどくさいので個人的にはあまり推してません。 どうしてもネットワークレベルで止めたい場合、こちらでCloudFrontのIPを確認できます。 動的に追加されたりしますので、正直めんどい。
Managed Prefix listでCloudFrontに対応してくれたらいいんですが、今はまだないです。。。(2020年9月17日時点)
ELB / HTTP Desync緩和モードの設定
HTTP Desync緩和モードで攻撃のリスクを緩和しましょう。
とりあえず、Defensiveくらいから始めるといいんじゃないでしょうか。 というか、機能がリリースされた段階でいずれかのモードになっているはずので、確認の上で適切なモードを選択してください。
ELB / 監視
ELBの健全性を監視しましょう。
CloudWatch metrics for your Application Load Balancer
異常なインスタンス数やエラー数などを監視しておくとよいのではないでしょうか。
通知にはChatbotを利用できます。
VPC / VPC FlowLogの作成
VPC Flow Logを有効化しましょう。
VPC内のフロー情報を保存し、インシデントの時の調査に役立てることができます。 なお、FlowLogを保存していなくてもGuardDutyやDetectiveを利用することは可能。
保存はS3とCloudWatch Logsをサポートしています。 コストを抑えたいならS3でどうぞ。
VPC / Security Groupで必要最小限のアクセスのみを許可
Security Groupで必要最小限度のアクセスだけを許可しましょう。
プロトコル、アクセス元のIPアドレス、アクセス元のAWSリソースに割り当てられているSecurity Groupに基づいてアクセス制御できます。 境界型の防御の有効性は「相対的に」下がっていますが、不要なわけではありません。 ちゃんとやりましょう。
小まとめ
ここまでの図をまとめるとこんな感じ。
文字が小さすぎて(以下略
サーバーの育てかた
次はサーバーです。
利用するサービス
- EC2
- EBS
- Inspector
- Systems Manager (Patch Manager)
- Systems Manager (Inventory)
- Systems Manager (Session Manager)
- Systems Manager (Parameter Store)
- CloudWatch
- CloudWatch Logs
- AWS Backup
育てる
やることは以下の通り。
- EC2 / Nitro Systemで動作するインスタンスタイプを利用
- EC2 / Key Pairの公開鍵をインポート
- EC2 / IAM Roleの割り当て
- EC2 / IMDSv2の有効化(を検討)
- EC2 / OSの設計を堅牢化(要件に応じたAMIの選択)
- EC2 / Time Sync Serviceで時刻同期
- EC2 + CloudWatch / AutoRecoveryの有効化
- EC2 / OS内のコンポーネントを最新化
- EBS + KMS / ボリュームの暗号化
- Inspector / 脆弱性を評価
- Systems Manager / SSM Agentのインストール
- Systems Manager (Patch Manager/RunCommand) / パッチスキャンおよびパッチ適用
- Systems Manager (Inventory) / インベントリの収集
- Systems Manager (Session Manager) / インスタンスの管理操作
- Systems Manager (Session Manager) / OSユーザーの指定
- Systems Manager (Session Manager) / ログの収集
- Systems Manager (Parameter Store) / データベースへの接続情報を保存
- CloudWatch / CloudWatch Agentで追加のメトリクスを収集
- CloudWatch / EC2インスタンスの監視
- CloudWatch Logs / ログの収集
- CloudWatch Logs / メトリクスフィルタによるログの監視
- CloudWatch Logs Insights / ログの分析
- AWS Backup / EC2インスタンスのバックアップ
- AWS Backup / イベントの通知
EC2 / Nitro Systemで動作するインスタンスタイプを利用
Nitro Systemに対応したインスタンスタイプを使いましょう。
Instances built on the Nitro System
セキュリティやパフォーマンスの面で従来のものより優れているので、是非利用しましょう。
ただし、古いインスタンスタイプからの移行の場合には少し注意が必要な場合もあります。
Migrating to latest generation instance types
EC2 / Key Pairの公開鍵をインポート
ローカルでキーペアを生成して公開鍵をインポートしましょう。
Option 2: Import your own public key to Amazon EC2
既存のEC2インスタンスのKeyを入れ替えることはできないので、新しく作るときはこうしましょうって話です。
秘密鍵含めてAWS側で生成することもできますが、ネットワーク上を通したくないとか、なんとなく気になる方はインポートする方法もあるので、お好みでどうぞ。
EC2 / IAM Roleの割り当て
AWSの認証情報をIAM Roleから取得できるようにしましょう。
AWSのAPIをCallする時にアクセスキーを利用することも可能ですが、半永久的に利用できる認証情報なので漏洩すると危険が危ないです。 なので、IAM Roleを割り当ててインスタンスメタデータから一時的なクレデンシャルを取得して利用するのがよいでしょう。
アプリケーションで利用していなくても、後述する様々な管理サービス(Systems Managerなど)で利用するので、必ず理解しておきましょう。
EC2 / IMDSv2の有効化(を検討)
SSRF対策としてIMDSv2を利用することを検討しましょう。
Configuring the instance metadata service
ただし、アプリケーションが対応しているか事前に確認していただく必要があります。
なお、AWSの認証情報を全く利用しないのであればメタデータへのアクセスを無効化するというのもありです。
EC2 / OSの設計を堅牢化(要件に応じたAMIの選択)
セキュリティ要件に応じて、セキュアなAMIを利用しましょう。
WindowsならSTIGに対応したAMIが無償で利用できます。
Amazon EC2 Windows Server AMIs for STIG compliance
マーケットプレイスでCIS Benchmarkに準拠したAMIを購入することもできる。
構築手順がちゃんと残っていて新規構築が可能なケースであれば、既存環境の改善で利用できる余地があるでしょう。 とは言っても、ここまでガチガチにする必要があるケースはそんなに多くないと思います。
EC2 / Time Sync Serviceで時刻同期
Time Sync Serviceで時刻同期をしましょう。
Setting the time for your Linux instance
Setting the time for a Windows instance
ログの時刻が間違ってたら、もうそれはログじゃないですね。
なお、インスタンス作成時に利用するAMIの提供時期やLinuxのディストリビューションによっては最初から設定済みの場合もあります。 よく確認しましょう。
EC2 + CloudWatch / AutoRecoveryの有効化
AutoRecoveryを利用してホストの障害に備えましょう。
AutoScalingを利用する際には利用することはないですが、長期間同じインスタンスを運用する環境であれば利用を検討するとよいのではないでしょうか。
この機能が動作する条件はやや限定的なので、仕様は正しく利用しよう。
EC2 / OS内のコンポーネントを最新化
OS内のコンポーネントを最新化しましょう。
Configuring your Windows instance
Windowsの場合、以下のようなコンポーネントを利用しています。
このほか、後述するSSM AgentやCloudWatch Agentが構成されていたらそれらも最新の状態に維持するべきです。
破壊的な変更がないかぎり、環境は最新化しましょう。 後述するSystems Managerを利用すれば、更新作業も簡単に実行できます。
EBS + KMS / ボリュームの暗号化
EBSボリュームを暗号化しましょう。
これは組織のセキュリティポリシー次第ですが、必要なら暗号化しておきましょう。
Inspector / 脆弱性を評価
EC2インスタンスの脆弱性を評価しましょう。
Getting started with Amazon Inspector
Inspector Agentをインストールすることで、EC2インスタンス内の脆弱性を検出できるようになります。
脆弱性が見つかった場合、リスクの内容に応じて対処するかどうか判断しましょう。 考え方自体はこちらが参考になります。 FutureVulsはいいぞ。
パッケージの脆弱性だけでなく、OSの構成やネットワークに関する脆弱な設定を検出することもできます。
Rules packages in Amazon Inspector
Systems Manager / SSM Agentのインストール
Systems Managerを利用するためにAgentをインストールしましょう。 なお、前述の通りAMIによってはインストール済みです。
Installing and configuring SSM Agent on EC2 instances for Linux
Installing and configuring SSM Agent on EC2 instances for Windows Server
後述する様々な機能を利用できます。 利用するにあたっては、IAM Role (Instance Profile)を通して必要な権限を付与しよう。
Step 4: Create an IAM instance profile for Systems Manager
Systems Manager (Patch Manager/RunCommand) / パッチスキャンおよびパッチ適用
適用するべきパッチの有無をスキャンし、必要に応じてパッチの適用を実行しましょう。
AWS Systems Manager Patch Manager
情報は、一番守りの薄いところから漏れます。 「桶の理論 セキュリティ」で検索してみてください。
最近はKernelのパッチ適用をオンラインでできるようにもなっている。
Use Kernel Live Patching on Amazon Linux 2 instances
パッチを個別にインストールしたい場合にはRunCommandが使いやすいかもしれません。 いろいろ試してみましょう。
Systems Manager (Inventory) / インベントリの収集
インベントリを収集しましょう。
どんなソフトウェアを利用しているかわからないと、意図せず所有している以上のライセンスを利用している状態になっているかもしれません。 まずは、現状把握から始めましょう。
ライセンスルールの強制までやりたい場合は、License Managerでどうぞ。
Systems Manager (Session Manager) / インスタンスの管理操作
EC2での管理操作はSession Managerを利用しましょう。
AWS Systems Manager Session Manager
従来はSecurity GroupでSSHやRDPのアクセスを許可する必要がありますが、 Session Managerを利用すればSecurity Groupでの許可は不要になります(Systems ManagerのAPIに対するアウトバウンドのみでOK)。
Systems Manager (Session Manager) / OSユーザーの指定
Session Managerで利用するOSユーザーを限定しましょう。
Enable run as support for Linux instances
IAMのエンティティに付与するタグやSession Managerの設定により、どのOSユーザーでセッションを開始するか指定できます。 セキュリティ要件に合わせて対応しましょう。
Systems Manager (Session Manager) / ログの収集
Session Managerによる接続および操作ログを取得しましょう。
Auditing and logging session activity
なお、接続の履歴はCloudTrailで取得できます。
接続後の操作はS3もしくはCloudWatch Logsにログを収集できるが、port forwarding および SSHでの接続ではサポートされていないので注意。
監視まではする必要ないと思いますが、抑止力として有効ではないでしょうか。
Systems Manager (Parameter Store) / データベースへの接続情報を保存
DBへの接続情報や設定などにParameter Storeを活用しましょう。
AWS Systems Manager Parameter Store
いろいろ修正が必要にはなるでしょうが、設定ファイルにハードコードするのはさすがにね。。。
CloudWatch / CloudWatch Agentで追加のメトリクスを収集
EC2インスタンスにCloudWatch Agentを利用して、標準のメトリクスには無い情報を取得しましょう。
CPUの利用率やネットワーク転送量などのメトリクスはデフォルトで取得できますが、メモリの利用率やディスクの利用率などのメトリクスはデフォルトでは取得できません。 必要に応じて取得しましょう。
IAM Roleに必要な権限を付与するのもお忘れなく。
Create IAM Roles and Users for Use with the CloudWatch Agent
ウィザードも便利です。
CloudWatch Agent Predefined Metric Sets
CloudWatch / EC2インスタンスの監視
EC2インスタンスの正常性を監視しましょう。
List the available CloudWatch metrics for your instances
CPU / Memoryの利用率の監視(通知)は必須じゃないと思っていて、もしリソースが逼迫していればCloudFrontやELBでレイテンシやステータスコードで異常を検知できるはずで、どちらかというとそちらを監視した方がいいのではないでしょうか。 やるなら、Anomaly Detectionで普段と異なる傾向を監視するくらいでしょうか。
Using CloudWatch Anomaly Detection
ディスクの空き容量は逼迫したタイミングでいきなり問題が顕在化するので、監視していた方がよいと思います。 それ以外にも、EC2インスタンスのステータスも監視しておくといいでしょう(必要に応じて、前述のAutoRecoveryを添えて)。
この辺は絶対的な答えはないと思いますが、絶対ダメなのはオオカミ少年化して通知を誰も見なくなるって状況を作ってしまうことだと思います。 通知を意味のあるものにしましょう。 最初から完璧なものはできないので継続的な改善が大事です。
CloudWatch Logs / ログの収集
必要なログを収集しましょう。
CloudWatch Agent Configuration File: Logs Section
トラブルシューティングなどの際に利用するようなログを保存しておきましょう。
機能が正常に動作しているか、等を確認することが主目的になるかと思います。 もちろん、ログによっては処理に要した時間などを出力させることもあるでしょう。 ここではログ自体の設計については述べませんが、システム運用に必要となる各種ログを整理して必要なものは収集して、保存・分析していきましょう。
CloudWatch Logs / メトリクスフィルタによるログの監視
ログの監視をしましょう。
Creating Metrics From Log Events Using Filters
例えば、アクセスログを監視して特定のステータスコードの数を監視する、といったことが考えられます。
ログからシステム管理者が何らかのアクションを必要とする状況を検知しなければならないのであれば、利用してみてください。
CloudWatch Logs Insights / ログの分析
ログの分析にCloudWatch Logs Insightsを利用しましょう。
Analyzing Log Data with CloudWatch Logs Insights
それなりに高度な絞り込みができて非常に便利です。
目grepできる人間はどこにでもいるわけじゃないんですよ。
AWS Backup / EC2インスタンスのバックアップ
EC2インスタンスをバックアップしましょう。
EC2インスタンス内にデータを保持していて、万が一EC2インスタンスが消滅したときにできるだけ直近の状態を復元する必要がある場合にはバックアップを取得しておきましょう。
データや設定情報を別のデータベースやParameter Storeなどのバックエンドサービスで管理し、EC2インスタンスはGolden AMIやAnsibleなどで復元できるようにしておくのが理想ではあります(バックアップ不要な状況にする)。
AWS Backup / イベントの通知
AWS Backupに関するイベントを通知しましょう。
Using Amazon SNS to Track AWS Backup Events
バックアップできてませんでしたー(てへぺろ)なんて状況が許されるはずがありません。
小まとめ
ここまでの内容をまとめるとこんな感じでしょうか。
データストアの育てかた
さて、最後のレイヤーです。
利用するサービス
- RDS
・・・今回の想定シーンだと、これだけですね。 RDS、めっちゃ多機能なんですよね。
育てる
やることは以下の通り。
- RDS / RDSインスタンスにデータベースを移行
- RDS / Multi-AZを有効化
- RDS / ボリュームを自動拡張
- RDS + KMS / ボリュームを暗号化
- RDS / 通信を暗号化
- RDS / バックアップを自動化
- RDS / Performance Insightsを有効化
- RDS / 拡張モニタリングを有効化
- RDS / ログを外部に出力
- RDS / マイナーバージョンアップグレードを管理
- RDS / 削除保護を有効化
- RDS / 重要なイベントを通知
RDS / RDSインスタンスにデータベースを移行
RDSを利用してデータベースを移行しましょう。 マネージドはいいぞ。
What Is Amazon Relational Database Service (Amazon RDS)?
現状のままではデータベースサーバーが単一障害点になりますし、データ保護やパフォーマンス管理も面倒です。 RDSに移行しましょう。 どのように便利なのかは、後述します。
なお、RDSの利用を検討する場合、制約に抵触しないかよく確認しましょう。 Oracle DatabaseやSQL Serverの場合は以下のページなどにRDSではサポートされていない機能が明記されています。 これ以外もちゃんと読みつつ、実際に検証して確認しましょう。
Oracle Database Feature Support
Features Not Supported and Features with Limited Support
データベースの移行にはいろんな方法を利用することができますので、状況に応じた方法を選択しましょう。
AWS Database Migration On-Demand Webinar
RDS / Multi-AZを有効化
Multi-AZを有効化しましょう。
High Availability (Multi-AZ) for Amazon RDS
マスターとなるインスタンスで障害が発生しても、すぐにフェールオーバーしてサービスを再開できます。
RDS / ボリュームを自動拡張
ボリュームが逼迫したら自動で拡張するように構成しましょう。
Managing Capacity Automatically with Amazon RDS Storage Autoscaling
データの急増が発生しても、サービス停止という事態を回避するのに役に立つでしょう。 もちろん、こういった状況が発生したということは認識するべきなので、後述するイベント監視は重要です。
RDS + KMS / ボリュームを暗号化
ボリュームを暗号化しましょう。
Encrypting Amazon RDS Resources
これも要件に応じて選択しましょう。
RDS / 通信を暗号化
必要に応じてデータベースクライアントとの通信を暗号化しましょう。
Using SSL/TLS to Encrypt a Connection to a DB Instance
これは、要件やセキュリティポリシーなどでエンドツーエンドの暗号化が要求される時などに利用するといいでしょう。 一般的にはVPC内の通信を暗号化する必要なケースは少ないはずです。
RDS / バックアップを自動化
RDSのバックアップを自動化しましょう。
Backing Up and Restoring an Amazon RDS DB Instance
バックアップウウィンドウや世代数を指定できます。 自動的に取得したスナップショットはインスタンスの削除と共に消える運命にあるので、そこだけ注意しましょう。 あとでデータが必要になる場合には事前に手動でスナップショットを作成しておきましょう。
RDS / Performance Insightsを有効化
Performance Insightsを有効化して遅い原因を分析しましょう。
Overview of Performance Insights
遅いクエリやその原因の特定を支援してくれます。
RDS / 拡張モニタリングを有効化
必要に応じて拡張モニタリングでOSレベルのメトリックを取得しましょう。
RDS / ログを外部に出力
各種ログをCloudWatch Logsに保存しましょう。
Publishing Database Logs to Amazon CloudWatch Logs
監査ログの取得できますが、すごい量(コスト)になるので必要な場合にだけ出力するようにしましょう。
RDS / マイナーバージョンアップグレードを管理
自動マイナーバージョンアップの有効化を検討しましょう。
Automatically Upgrading the Minor Engine Version
バージョンアップに伴うダウンタイムのタイミングを制御したい場合には無効にしておきましょう。 ただし、AWS Health APIから発行されるイベントを監視して、マイナーバージョンアップが必要な状況が発生していないか監視しておきましょう。
RDS / 削除保護を有効化
削除保護を有効化しましょう。
データが死ぬとサービスが死ぬと思うので、保険として有効化しておくとよいのではないでしょうか。
RDS / 重要なイベントを通知
重要なイベントを通知しましょう。
Using Amazon RDS Event Notification
フェールオーバーの発生など、サービスの可用性・パフォーマンスなどに重大な影響が発生していると思われるイベントの発生を監視しましょう。
小まとめ
ということで、完成したものがこちら。
でかい(小並感)
考察
いかがでしたでしょうか。
いやー、この記事書くのにめっちゃ時間かかりましたw
AWSのサービスは「部品」
こういった改善はちょっとずつ積み重ることができるし、AWSの各種サービスはそういうふうにできている。
この記事を書いていて改めて感じました。
多くの課題を抱えているとどこから手をつけていいか分からなくなりがちですが、冷静に今の環境とその課題を整理し、順番に片付けていきましょう。 今回は「AWSアカウント」「ネットワーク」「サーバー」「データストア」に分類してできることを整理しました。 あとは「アプリケーション」のレイヤーについても検討できればよいでしょう。
全部やる必要があるのか
ないです。
適切な設計をしなかったことによって起こりうる問題の影響度や発生する可能性などを鑑み、 優先度をつけながら投資できる範囲でやっていくしかありません。
何をやって、何をやらないか、考えていきましょ!
理想を思い描いていくことからはじめる
この記事で紹介した内容はあくまでも手段です。 手段を実行する場合、目的があるはずです。
・・・ありますよね?
例えば、様々なセキュリティ対策は第三者による攻撃や内部不正に対して「予防」「検知」「防御」「対応」「復旧」などを実現するために実施されます。 この分類は、NISTのサーバーセキュリティフレームワークで定義されています。 他にもいろんなフレームワークがあるので参考にするとよいでしょう。
【解説】NIST サイバーセキュリティフレームワークの実践的な使い方
監視は正常にサービスをデリバリーできていることを確認し、問題があれば復旧にすぐ着手できるようにするために行われます。 また、迅速にサービスを復旧させるためには監視をしているだけではダメで、問題を特定できるようにするためのログやメトリクスを予め取得しておく必要がありますし、容易に分析するための手段を用意しておくことも重要です。 それ以前に、一部のコンポーネントが壊れてもサービス提供を継続できるようにしておくことが何よりも重要です。 いずれにしても、突き詰めれば「適切な価値提供を継続したい」ってところに行き着くと思います。
求めるものが異なれば、今日紹介したこと意外にもやるべきことは多々あるでしょう。 まずは、理想を確認するところからはじめてはどうでしょうか。
まとめ
ということで、冴えないAWS環境を一通り改善までの流れを書いてみました。 やったこととしては、「新しい要素を追加」「サーバー内の機能を分離してマネージドサービスで実現」の繰り返しかなーという感じでしたね。
状況によっては他にもやるべきことがあると思います。 ぜひご意見をいただければと思います。
現場からは以上です。